import numpy as np
import matplotlib.pyplot as plt


class fluctuation():
    def __init__(self, data):
        self.sequence_data = data[:, :-1]
        self.target = data[:, -1]
        self.T = data.shape[0]  # 时间长度
        self.N = data.shape[1] - 1   # 变量个数
        self.delta_list = np.mean(self.sequence_data, axis=0)

    def gene_equation(self, line, time_lag=None):
        a,b,c,d,e,f,g,h,i,j,k = line

        # # delay = 1
        # l = time_lag
        # return (((l)*((k)/((h)+((l)+(l)))))+((l)*((l)/((e)+((l)+(g))))))+((a)+(b))

        # delay = 0
        # return ((((i)*((j)/((g)-(a))))*(k))+((f)/((d)+((k)*(k)))))+(((e)*((k)/((g)+(h))))*(k))
        return (((((g)+(j))+((f)+(a)))*(((f)+(i))+((k)+(f))))+((((k)+(k))+((k)+(k)))*(((k)+(k))+((k)+(k)))))+((((k)+(k))+((k)+(k)))*(((k)+(k))+((k)+(k))))
    # 计算扰动,0<= t <= T-1
    def calculate_disturbance(self, variable, delta=None):
        if delta is None:
            delta = self.delta_list[variable]

        delta_line = np.zeros(self.N)
        delta_line[variable] += delta

        original_f = np.array([self.gene_equation(line) for line in self.sequence_data])
        dis_f = np.array([self.gene_equation(line+delta_line) for line in self.sequence_data])

        return dis_f - original_f

    # 计算单个变量的波动
    def calculate_one_fluctuation(self, variable, delta=None):
        disturbances = self.calculate_disturbance(variable, delta)
        one_fluctuation = np.sum(disturbances ** 2)
        return one_fluctuation

    # 计算所有自变量的波动
    def calculation_all_fluctuation(self, delta_list=None):
        if delta_list is None:
            delta_list = self.delta_list

        original_f = np.array([self.gene_equation(line) for line in self.sequence_data])
        dis_f = np.array([self.gene_equation(line+delta_list) for line in self.sequence_data])
        all_fluctuation = dis_f - original_f
        return all_fluctuation

    # 计算max(f(x)) - min(f(x))
    def calculate_maxf_subtraction_mixf(self):
        maxf, minf = 0, 0

        for t in range(0, self.T):
            original_line = self.sequence_data[t]
            tempf = self.gene_equation(original_line)
            if maxf < tempf:
                maxf = tempf
            if minf > tempf:
                minf = tempf
        return maxf - minf

    # 画图查看扰动后的结果
    def pl(self, i, delta):
        delta_line = np.zeros(self.N)
        delta_line[i] += delta

        original_f = [self.gene_equation(line) for line in self.sequence_data[:1000, :]]
        dis_f = [self.gene_equation(line+delta_line) for line in self.sequence_data[:1000, :]]

        plt.plot(self.target[:1000], 'r')
        plt.plot(original_f, 'g')
        # plt.plot(dis_f, 'b')
        plt.show()


inputfile = "../process_data/data/kaggle_bike_processed.csv"

dataSet = np.loadtxt('data/data_kaggle_bike.txt')

fluct = fluctuation(dataSet)
print(fluct.sequence_data.shape)
print(fluct.target.shape)
dis = fluct.calculate_disturbance(4, fluct.delta_list[4])
# plt.plot(dis[:1000], 'r')
# plt.show()
fluct.pl(4, fluct.delta_list[4])
# fluct_temp = fluct.calculate_one_fluctuation(4, fluct.delta_list[4])
#
# max_min = fluct.calculate_maxf_subtraction_mixf()
# print(fluct_temp)
# print(fluct.T * max_min)
# all_flu = fluct.calculation_all_fluctuation()
# print(np.sum(all_flu))
# print(all_flu)
